//
//  ApiClient.m
//  QFBAPP
//
//  Created by 无常先生 on 2018/5/2.
//  Copyright © 2018年 YIXun. All rights reserved.
//

#import "ApiClient.h"
#import "NSArray+Model.h"

@interface ApiClient ()

@property (nonatomic, strong, readwrite) AFHTTPSessionManager *sessionManager;

@property (nonatomic, strong) NSMutableURLRequest *request;
// 当前的任务
@property (nonatomic, strong) NSURLSessionDataTask *task;
@end

@implementation ApiClient

- (instancetype)init {
    return [self initWithServer:nil];
}

- (instancetype)initWithServer:(nullable NSObject<ApiSeriverProtocol> *)server {
    self = [super init];
    if (self) {
        _server = server;
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        configuration.URLCache = nil;
        _sessionManager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil sessionConfiguration:configuration];
        
        _sessionManager.requestSerializer = [self clientHTTPHeaderField];
        _sessionManager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
        
        _sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",@"text/plain", nil];
        
    }
    return self;
}

#pragma mark - public methods
- (RACSignal *)rac_GET:(NSString *)path parameters:(nullable id)parameters modelClass:(__unsafe_unretained Class)modellClass{
    return [[self rac_requestPath:path parameters:parameters method:@"GET" modelClass:modellClass]
            setNameWithFormat:@"%@ -rac_GET: %@, parameters: %@", self.class, path, parameters];
}

- (RACSignal *)rac_POST:(NSString *)path parameters:(nullable id)parameters modelClass:(__unsafe_unretained Class)modellClass{
    return [[self rac_requestPath:path parameters:parameters method:@"POST" modelClass:modellClass]
            setNameWithFormat:@"%@ -rac_POST: %@, parameters: %@", self.class, path, parameters];
}

- (RACSignal *)rac_DELETE:(NSString *)path parameters:(nullable id)parameters modelClass:(__unsafe_unretained Class)modellClass{
    return [[self rac_requestPath:path parameters:parameters method:@"DELETE" modelClass:modellClass]
            setNameWithFormat:@"%@ -rac_DELETE: %@, parameters: %@", self.class, path, parameters];
}

- (RACSignal *)rac_PUT:(NSString *)path parameters:(nullable id)parameters modelClass:(__unsafe_unretained Class)modellClass{
    return [[self rac_requestPath:path parameters:parameters method:@"PUT" modelClass:modellClass]
            setNameWithFormat:@"%@ -rac_PUT: %@, parameters: %@", self.class, path, parameters];
}

- (RACSignal *)rac_requestPath:(NSString *)path parameters:(nullable id)parameters method:(NSString *)method modelClass:(Class) modelClass{
    // 保存 当前模型对象
    if (modelClass) {
        [[ApiClient dictionaryOfEndpointClasses] setObject:modelClass forKey:path];
    }
    NSLog(@"+++++++%@",path);
    @weakify(self);
    return [RACSignal createSignal:^(id<RACSubscriber> subscriber) {
        @strongify(self);
        NSString *urlString = nil;
        urlString = path;
//        if ([path containsString:@"http"]) {
//            urlString = path;
//        } else {
//            urlString = [[NSURL URLWithString:path relativeToURL:[NSURL URLWithString:self.server.serverUrl]] absoluteString];
//        }
        self.sessionManager.requestSerializer = [self clientHTTPHeaderField];
        self.request = [self.sessionManager.requestSerializer requestWithMethod:method
                                                                      URLString:urlString
                                                                     parameters:parameters
                                                                          error:nil];
        
       NSURLSessionDataTask *task = [self.sessionManager dataTaskWithRequest:self.request uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
            
        } downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
            
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            if (error) {
                [subscriber sendError:[NSError errorWithDomain:error.domain code:error.code userInfo:error.userInfo]];
            } else {
                NSObject *responseModel = nil;
                if (responseObject) {
                    responseModel =
                    [self resolveResponse:(NSHTTPURLResponse *)response endpoint:path responseObject:responseObject[@"data"]];
                    
                    NSLog(@"1111responseObject[@data]=%@",responseObject[@"data"]);
                }
                if (responseModel) {
                    [subscriber sendNext:RACTuplePack(responseModel,responseObject)];
                }else {
                    [subscriber sendNext:RACTuplePack(nil, responseObject)];
                }
                [subscriber sendCompleted];
            }
            
        } ];
        [task resume];
        self.task = task;
        return [RACDisposable disposableWithBlock:^{
            [task cancel];
        }];
    }];
}

- (RACSignal *)rac_POST:(NSString *)path
             parameters:(nullable id)parameters
constructingBodyWithBlock:(void (^)(id<AFMultipartFormData> formData))block Progress:(ProgressBlock)progressBlock{
    @weakify(self);
    return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
        @strongify(self);
        NSString *urlString = nil;
        if ([path containsString:@"http"]) {
            urlString = path;
        } else {
            urlString = [[NSURL URLWithString:path relativeToURL:[NSURL URLWithString:self.server.serverUrl]] absoluteString];
        }
        self.sessionManager.requestSerializer = [self clientHTTPHeaderField];
        self.request = [self.sessionManager.requestSerializer
                        multipartFormRequestWithMethod:@"POST"
                        URLString:[[NSURL URLWithString:urlString
                                          relativeToURL:[NSURL URLWithString:self.server.serverUrl]] absoluteString]
                        parameters:parameters
                        constructingBodyWithBlock:block
                        error:nil];
        
        NSURLSessionDataTask *task = [self.sessionManager dataTaskWithRequest:self.request uploadProgress:^(NSProgress * _Nonnull uploadProgress) {
            if (progressBlock) {
                progressBlock(uploadProgress);
            }
        } downloadProgress:^(NSProgress * _Nonnull downloadProgress) {
            
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            if (error) {
                
            }else {
                [subscriber sendNext:responseObject];
                [subscriber sendCompleted];
            }
        }];
        
        [task resume];
        return [RACDisposable disposableWithBlock:^{
            [task cancel];
        }];
    }] setNameWithFormat:@"%@ -rac_POST: %@, parameters: %@, constructingBodyWithBlock:", self.class, path, parameters];
}


+ (NSMutableDictionary<NSString *, Class> *)dictionaryOfEndpointClasses {
    static NSMutableDictionary<NSString *, Class> *dictionaryOfEndpointClasses = nil;
    if (!dictionaryOfEndpointClasses) {
        dictionaryOfEndpointClasses = [NSMutableDictionary dictionary];
    }
    
    return dictionaryOfEndpointClasses;
}

+ (nullable Class)getResponseClass:(NSString *)endpoint {
    NSDictionary *endpointClasses = [self dictionaryOfEndpointClasses];
    __block id cls = [endpointClasses objectForKey:endpoint];
    if (cls) {
        return cls;
    }
    
    [endpointClasses enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, Class obj, BOOL * _Nonnull stop) {
        if ([key containsString:@"%@"]) {
            NSString *endpointPattern = [key stringByReplacingOccurrencesOfString:@"%@" withString:@"*"];
            NSError *error = nil;
            NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:endpointPattern options:NSRegularExpressionCaseInsensitive error:&error];
            NSRange matchRange = [regex rangeOfFirstMatchInString:endpoint options:NSMatchingReportProgress range:NSMakeRange(0, endpoint.length)];
            if (matchRange.location != NSNotFound) {
                cls = obj;
                stop = YES;
            }
        }
    }];
    
    return cls;
}
//+ (void)setResponseClass:(Class)responseClass forEndpoint:(NSString *)endpoint {
//    [[self dictionaryOfEndpointClasses] setObject:responseClass forKey:endpoint];
//}

- (nullable NSObject *)resolveResponse:(NSHTTPURLResponse *)response
                              endpoint:(NSString *)endpoint
                        responseObject:(id)responseObject {
    id responseModel = responseObject;
    Class responseClass = [self.class getResponseClass:endpoint];
    if (responseClass) {
        if ([responseObject isKindOfClass:NSArray.class]) {
            responseModel = [NSArray modelArrayWithClass:responseClass json:responseObject];
        } else {
            responseModel = [responseClass modelWithJSON:responseObject];
        }
    }
    return responseModel;
}


// 需要子类重写的方法
- (AFHTTPRequestSerializer *)clientHTTPHeaderField {
    
    return [AFHTTPRequestSerializer serializer];
}

- (void)requestErrorWithErrorCode:(NSError *)error {
    
}

@end
